package com.authentications.service;

import com.authentications.oauth2.auc.Oauth2ResourceServerConfigurer;
import com.authentications.oauth2.auc.Oauth2WebSecurityConfig;
import com.authentications.oauth2.auc.handler.Oauth2BearerTokenExtractor;
import com.authentications.oauth2.info.Oauth2Value;
import com.authentications.strategy.OpenOauth2;
import com.authentications.utils.SpringContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

/**
 * @ClassName Oauth2AucServiceAutoConfiguration
 * @Author xiezhuocai
 * @Description Spring Security Oauth2 jwt鉴权
 * @Date 2021/12/20 14:21
 */
@Configuration
@EnableResourceServer
@EnableConfigurationProperties(Oauth2Value.class)
@ConditionalOnBean({OpenOauth2.class})
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true,jsr250Enabled = true)
public class Oauth2AucServiceAutoConfiguration {

    @Autowired
    private Oauth2Value oauth2Value;

    @Bean
    public SpringContextUtils springContextUtils() {
        return new SpringContextUtils();
    }

    @Bean
    public TokenStore tokenStore(){
        return new JwtTokenStore(accessTokenConverter());//策略模式使用Jwt来存存储令牌
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter(){
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        if (oauth2Value.getSigning_key()  != null) converter.setSigningKey(oauth2Value.getSigning_key());
        if (oauth2Value.getSigning_key()  == null)  converter.setSigningKey("admin");
        return converter;
    }


    @Bean
    @ConditionalOnMissingBean(ResourceServerConfigurer.class)
    public Oauth2ResourceServerConfigurer resourceServerConfigurer(){
        return new Oauth2ResourceServerConfigurer(oauth2Value);
    }

    @Bean
    public Oauth2BearerTokenExtractor iamBearerTokenExtractor(){
        return new Oauth2BearerTokenExtractor(accessTokenConverter());
    }

    @Bean
    public Oauth2WebSecurityConfig webSecurityConfig(){
        return new Oauth2WebSecurityConfig();
    }
}
